// /////////////////////////////////////////////////////////////////////////////
//
// Name:            SerializedAttributes.h
// Author:          Michael Bartsch (ZCCdark203)
//
// Desc :           Declaration of the SerializedAttributes class.
//
// License:         Copyright (C) 2009 Michael Bartsch and Contributors
//
//                  This program is free software: you can redistribute it
//                  and/or modify it under the terms of the zlib/libpng License.
//                  See main.cpp for conditions of distribution and use.
//
// /////////////////////////////////////////////////////////////////////////////

#ifndef __SERIALIZEDATTRIBUTES_H__
#define __SERIALIZEDATTRIBUTES_H__

// Include files
#include "../dependencies.h"
#include "ReferenceCounted.h"
#include "Serializable.h"
#include "SerializedAttribute.h"

// Forward declarations
class SerializedAttribute;


// SerializedAttributes class
//! The SerializaedAttributes class describes a FIFO collection of serialized
//! attributes. This class provides various methods to manage these attributes.
class SerializedAttributes : public Serializable
{
public:

    // Initialisation and deinitialisation
    //! Constructor
    SerializedAttributes();
    //! Deconstructor
    ~SerializedAttributes();

    // Public methods
    //! Returns whether there are attributes in the internal queue.
    bool isEmpty() const;

    // Serializes this object.
    bool onSerialization(SerializedAttributes *attributes);
    // Deserializes this object.
    bool onDeserialization(SerializedAttributes *attributes);

    //! Pulls the first attribute from the internal attribute queue.
    SerializedAttribute* pullAttribute();

    //! Pulls an attribute from the queue and interprete it as an aabbox3df object.
    aabbox3df    pullAabbox3df();
    //! RPulls an attribute from the queue and interprete it as an aabbox3di object.
    aabbox3di    pullAabbox3di();
    //! Pulls an attribute from the queue and interprete it as a boolean value.
    bool         pullBool();
    //! Pulls an attribute from the queue and interprete it as a SColor object.
    SColor       pullColor();
    //! Pulls an attribute from the queue and interprete it as a SColorf object.
    SColorf      pullColorf();
    //! Pulls an attribute from the queue and interprete it as a dimension2df object.
    dimension2df pullDimension2df();
    //! Pulls an attribute from the queue and interprete it as a dimension2di object.
    dimension2di pullDimension2di();
    //! Pulls an attribute from the queue and interprete it as a float value.
    f32          pullFloat();
    //! Pulls an attribute from the queue and interprete it as an integer value.
    s32          pullInt();
    //! Pulls an attribute from the queue and interprete it as a line2df object.
    line2df      pullLine2df();
    //! Pulls an attribute from the queue and interprete it as a line2di object.
	line2di      pullLine2di();
	//! Pulls an attribute from the queue and interprete it as a line3df object.
	line3df      pullLine3df();
	//! Pulls an attribute from the queue and interprete it as a line3di object.
	line3di      pullLine3di();
	//! Pulls an attribute from the queue and interprete it as a Serializable object.
	Serializable* pullObject();
	//! Pulls an attribute from the queue and interprete it as a plane3df object.
	plane3df     pullPlane3df();
	//! Pulls an attribute from the queue and interprete it as a plane3di object.
	plane3di     pullPlane3di();
	//! Pulls an attribute from the queue and interprete it as a quaternion object.
	quaternion   pullQuaternion();
	//! Pulls an attribute from the queue and interprete it as a rect<s32> object.
	rect<s32>    pullRect();
	//! Pulls an attribute from the queue and interprete it as a string.
	std::string  pullString();
	//! Pulls an attribute from the queue and interprete it as a wide string.
	stringw      pullStringW();
	//! Pulls an attribute from the queue and interprete it as a vector2df object.
    vector2df    pullVector2df();
    //! Pulls an attribute from the queue and interprete it as a vector2di object.
    vector2di    pullVector2di();
    //! Pulls an attribute from the queue and interprete it as a vector3df object.
    vector3df    pullVector3df();
    //! Pulls an attribute from the queue and interprete it as a vector3di object.
    vector3di    pullVector3di();

    //! Pushes a new attribute into the internal attribute queue.
    void pushAttribute(SerializedAttribute *attribute);

    //! Pushes an attribute into the queue as an aabbox3df object.
    void pushAabbox3df(const std::string &name, const aabbox3df &value);
    //! Pushes an attribute into the queue as an aabbox3di object.
    void pushAabbox3di(const std::string &name, const aabbox3di &value);
    //! Pushes an attribute into the queue as a boolean value.
    void pushBool(const std::string &name, bool value);
    //! Pushes an attribute into the queue as a SColor object.
    void pushColor(const std::string &name, const SColor &value);
    //! Pushes an attribute into the queue as a SColorf object.
    void pushColorf(const std::string &name, const SColorf &value);
    //! Pushes an attribute into the queue as a dimension2df object.
    void pushDimension2df(const std::string &name, const dimension2df &value);
    //! Pushes an attribute into the queue as a dimension2di object.
    void pushDimension2di(const std::string &name, const dimension2di &value);
    //! Pushes an attribute into the queue as a float value.
    void pushFloat(const std::string &name, f32 value);
    //! Pushes an attribute into the queue as an integer value.
    void pushInt(const std::string &name, s32 value);
    //! Pushes an attribute into the queue as a line2df object.
    void pushLine2df(const std::string &name, const line2df &value);
    //! Pushes an attribute into the queue as a line2di object.
    void pushLine2di(const std::string &name, const line2di &value);
    //! Pushes an attribute into the queue as a line3df object.
    void pushLine3df(const std::string &name, const line3df &value);
    //! Pushes an attribute into the queue as a line3di object.
    void pushLine3di(const std::string &name, const line3di &value);
    //! Pushes an attribute into the queue as a Serializable object.
    void pushObject(const std::string &name, Serializable *object);
    //! Pushes an attribute into the queue as a plane3df object.
    void pushPlane3df(const std::string &name, const plane3df &value);
   //! Pushes an attribute into the queue as a plane3di object.
    void pushPlane3di(const std::string &name, const plane3di &value);
    //! Pushes an attribute into the queue as a quaternion object.
    void pushQuaternion(const std::string &name, const quaternion &value);
    //! Pushes an attribute into the queue as a rect<s32> object.
    void pushRect(const std::string &name, const rect<s32> &value);
    //! Pushes an attribute into the queue as a string.
    void pushString(const std::string &name, const std::string &value);
    //! Pushes an attribute into the queue as a wide string.
    void pushStringW(const std::string &name, const stringw &value);
    //! Pushes an attribute into the queue as a vector2df object.
    void pushVector2df(const std::string &name, const vector2df &value);
    //! Pushes an attribute into the queue as a vector2di object.
    void pushVector2di(const std::string &name, const vector2di &value);
    //! Pushes an attribute into the queue as a vector3df object.
    void pushVector3df(const std::string &name, const vector3df &value);
    //! Pushes an attribute into the queue as a vector3di object.
    void pushVector3di(const std::string &name, const vector3di &value);

private:

    // Private methods
    void removeAttributes();
    void moveAttributesTo(SerializedAttributes *attributes);

    // Private members
    queue<SerializedAttribute*> mQueue;
};

#endif
